<?php
class Route {

	private $pattern = '';
	private $properties = array();
	private $regex = array();
	private $urlValues = array();
	private $useAuth = false;
	private $authUserType = null;
	
	private static $pageClass = 'Page';
	private static $patterns = array();

	public static function register($pattern, $properties) {
		$p = new Route($pattern, $properties);
		self::$patterns[] = $p;
		return $p;
	}
	
	public static function setPageClass($className){
		self::$pageClass = $className;
	}
	
	public static function getRoutes(){
		return self::$patterns;
	}
	
	public static function executeMatch($q){
		$flag = false;
		$routes = self::getRoutes();
		for($i = 0;$i < count($routes);$i++){
			if($routes[$i]->matches($q)){
				$flag = true;
				$routes[$i]->execute();
				break;
			}
		}
		if(!$flag){
			echo 'Page not found. q: '.$q;
		}
	}

	public function __construct($pattern, $properties) {
		$this->pattern = $pattern;
		$this->properties = $properties;
	}
	
	public function regex($name, $pattern){
		$this->regex[$name] = $pattern;
		return $this;
	}
	
	public function auth($userType = null){
		$this->useAuth = true;
		$this->authUserType = $userType;
		return $this;
	}
	
	public function matches($url){
		$pattern = $this->pattern;
		if(count($this->regex) == 0){
			return $this->pattern == $url;
		}
		foreach($this->regex as $name => $pat){
			$count = 0;
			$pattern = str_replace('{'.$name.'}', '(?P<'.$name.'>'.$pat.')', $pattern, $count);
			if($count == 0){
				throw new ErrorException('Route: variable with name: '.$name.' does not exist.');
			}
		}
		$flag = preg_match('#^'.$pattern.'$#', $url, $matches);
		foreach($this->regex as $name => $pat){
			if(isset($matches[$name])){
				$this->urlValues[] = $matches[$name];
			}else{
				$flag = false;
			}
		}
		
		return $flag;
	}
	
	public function execute(){
		if($this->useAuth && !Auth::check($this->authUserType)){
			//TODO dit beter met redirect.
		}
		if(isset($this->properties['controller'])){
			list($class, $method) = explode('@', $this->properties['controller']);
			$c = new $class();	
			$reflectionMethod = new ReflectionMethod($class, $method);
			$reflectionMethod->invokeArgs($c, $this->urlValues);
			echo $c->respond();
		}elseif(isset($this->properties['script'])){
			if(file_exists('app/'.$this->properties['script'])){
				require('app/'.$this->properties['script']);
			}else{
				echo 'Missing script: app/'.$this->properties['script'];
			}
		}elseif(isset($this->properties['page'])){
			$page = new self::$pageClass();
			if(isset($this->properties['title'])){
				$page->setTitle($this->properties['title']);
			}
			ob_start();
			require('app/'.$this->properties['page']);
			$page->setContent(ob_get_clean());
			echo $page->respond();
		}else{
			echo 'No action found.';
		}		
	}

}
?>